#include <time.h>
#include <v8.h>
#include <fstream>

#include "js/vector.h"
#include "js/quaternion.h"
#include "js/node.h"
#include "js/input.h"
#include "js/world.h"
#include "js/camera.h"
#include "js/connection.h"
#include "js/entity.h"
#include "js/skeleton.h"
#include "js/bone.h"
#include "js/animation.h"
#include "js/desktop.h"

#include "wonderland.h"
#include "render_engine.h"
#include "gui.h"
#include "scripting_context.h"
#include "curl_resource.h"
#include "xmpp_connection.h"
#include "sync_manager.h"
#include "serialize.h"


#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
	INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
	int main(int argc, char **argv)
#endif
{
  srand(time(NULL));

  RenderEngine *region = new RenderEngine;
  region->initialize();

  Wonderland::Gui gui(region);

  Wonderland::ScriptingContext *context = new Wonderland::ScriptingContext;

  // Initialize javascript bindings
  JSVector::Initialize(context);
  JSQuaternion::Initialize(context);
  JSEntity::Initialize(context);
  JSSkeleton::Initialize(context);

  JSNode::Initialize(context, region);
  JSBone::Initialize(context, region);
  JSAnimation::Initialize(context, region);

  JSWorld::Initialize(context);
  context->setGlobal("world", JSWorld::New(region));

  JSCamera::Initialize(context);
  context->setGlobal("camera", JSCamera::New(region->getSceneManager()->getCamera("/Viewer/Camera")));

  JSInput::Initialize(context);
  context->setGlobal("oisinput", JSInput::New(region->getInputListener()));

  JSDesktop::Initialize(context, &gui);
  context->setGlobal("desktop", JSDesktop::New());

	Wonderland::XmppConnection *xmpp = new Wonderland::XmppConnection;
	// .. connection established via javascript ..

	Wonderland::SyncManager *sync = new Wonderland::SyncManager(xmpp, region);
	region->setSyncManager(sync);
	// Ready to go...
	
	
	JSConnection::Initialize(context);
	context->setGlobal("connection", JSConnection::New(xmpp));

	// ...
	//test_curl("http://bennolan.com/wonderland/resources/ram.zip");

	// Creates the scene, including avatar, etc
	region->start();

	// Load javascripts
	if(!context->loadAndEvaluate(Wonderland::Locations::Resources() + "scripts/standard_library.js")){
		exit(-1);
	}
	if(!context->loadAndEvaluate(Wonderland::Locations::Resources() + "scripts/test.js")){
		exit(-1);
	}
	if(!context->loadAndEvaluate(Wonderland::Locations::Resources() + "scripts/environment.js")){
		exit(-1);
	}

	int cont = 1;
	
	while(cont){
	cont = region->renderOneFrame();

	context->evaluate("Event.dispatch(viewer, 'frameEnded')");

	xmpp->poll();
	sync->poll();
	}

	return 0;
}